#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "formtemp.h"
#include <QMessageBox>
/*********************************************************************************************************
*                                             常量定义
*********************************************************************************************************/
//模块ID
const uchar DAT_SYS     = 0x01;          //系统信息
const uchar DAT_ECG     = 0x10;          //心电信息
const uchar DAT_RESP    = 0x11;          //呼吸信息
const uchar DAT_TEMP    = 0x12;          //体温信息
const uchar DAT_SPO2    = 0x13;          //血氧信息
const uchar DAT_NIBP    = 0x14;          //无创血压信息

//二级ID
const uchar DAT_TEMP_DATA   = 0x02;  //体温实时数据

const uchar DAT_NIBP_CUFPRE = 0x02;  //无创血压实时数据
const uchar DAT_NIBP_END    = 0x03;  //无创血压测量结束
const uchar DAT_NIBP_RSLT1  = 0x04;  //无创血压测量结果1
const uchar DAT_NIBP_RSLT2  = 0x05;  //无创血压测量结果2

const uchar DAT_RESP_WAVE   = 0x02;  //呼吸波形数据
const uchar DAT_RESP_RR     = 0x03;  //呼吸率

const uchar DAT_SPO2_WAVE   = 0x02;  //血氧波形数据
const uchar DAT_SPO2_DATA   = 0x03;  //血氧数据

const uchar DAT_ECG_WAVE    = 0x02;  //心电波形数据
const uchar DAT_ECG_LEAD    = 0x03;  //心电导联信息
const uchar DAT_ECG_HR      = 0x04;  //心率

const int PACK_QUEUE_CNT = 4000;     //包数量

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle(tr("ParamMonitor"));
    setFixedSize(this->width(),this->height());

    ui->ecg1WaveLabel->setStyleSheet("border:1px solid black;");
    ui->ecg2WaveLabel->setStyleSheet("border:1px solid black;");
    ui->spo2WaveLabel->setStyleSheet("border:1px solid black;");
    ui->respWaveLabel->setStyleSheet("border:1px solid black;");

    //菜单栏设置
    ui->menuBar->addAction(tr("串口设置"), this, SLOT(menuSetUART()));
    ui->menuBar->addAction(tr("数据存储"), this, SLOT(menuSaveData()));
    ui->menuBar->addAction(tr("关于"), this, SLOT(menuAbout()));
    ui->menuBar->addAction(tr("退出"), this, SLOT(menuQuit()));

    //状态栏设置
    m_first_status_label = new QLabel();
    m_first_status_label->setMinimumSize(200, 18); //设置标签最小尺寸
    QFont font("Microsoft YaHei", 10, 50);
    m_first_status_label->setFont(font);
    m_first_status_label->setText(tr("串口未配置"));
    ui->statusBar->addWidget(m_first_status_label);

    m_pack_unpack=new PackUnpack();
    m_pack_after_unpack_array = new uchar* [PACK_QUEUE_CNT];
    for (int i=0;i<PACK_QUEUE_CNT;i++ ) {
        m_pack_after_unpack_array[i]=new uchar[10]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    }

    uiInit();  //初始化参数
    ui->tempInfoGroupBox->installEventFilter(this);  //设置被监控控件--配合eventfilter使用
}

MainWindow::~MainWindow()
{
    delete ui;
    delete m_pack_unpack;
    delete m_first_status_label;
    //二维数组如何释放？

}

void MainWindow::uiInit()
{
    m_serial_port = nullptr;

    m_pack_head = -1;    //当前需要处理的缓冲包的序号
    m_pack_tail = -1;    //最后处理的缓冲包的序号，mPackHead不能追上mPackTail,追上的话表示收到的数据超出2000的缓冲

    //初始化体温探头
    m_prb_type  = "YSI";
}

bool MainWindow::eventFilter(QObject* obj,QEvent* event)
{
    if(obj == ui->ecgInfoGroupBox)
    {

    }
    else if(obj == ui->nibpInfoGroupBox)
    {

    }
    else if(obj == ui->spo2InfoGroupBox)
    {

    }
    else if(obj == ui->respInfoGroupBox)
    {

    }
    else if(obj == ui->tempInfoGroupBox)
    {
        if(event->type()==QEvent::MouseButtonPress)
        {
            if(m_serial_port!=nullptr&&m_serial_port->isOpen())
            {
                FormTemp* form_temp= new FormTemp(m_prb_type);
                form_temp->show();
                connect(form_temp,SIGNAL(sendTempData(QString, QByteArray)),this,SLOT(rec_prb_type(QString,QByteArray)));
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return QMainWindow::eventFilter(obj,event);
    }
}


void MainWindow::menuSetUART()
{
    FormSetUART *form_set_UART = new FormSetUART();
    connect(form_set_UART, SIGNAL(uartSetData(QString, int, int, int, int, bool)), this, SLOT(initSerial(QString, int, int, int, int, bool)));
    form_set_UART->show();
}

void MainWindow::menuAbout()
{

}

void MainWindow::menuQuit()
{
    QMessageBox meg(QMessageBox::Question, tr("退出"), tr("是否退出程序？"), nullptr);
    QPushButton *okButton = meg.addButton(tr("确定"), QMessageBox::AcceptRole);
    QPushButton *cancelButton = meg.addButton(tr("取消"), QMessageBox::RejectRole);
    meg.exec();

    if((QPushButton*)meg.clickedButton() == okButton)//点击确定
    {
        QApplication* app;
        app->exit(0);
    }
    else if((QPushButton*)meg.clickedButton() == cancelButton)
    {
    }
}

void MainWindow::initSerial(QString port_num,int baud_rate,int data_bits,int stop_bits,int parity,bool is_opened)
{
    if(!is_opened)
    {
        m_serial_port=new QSerialPort();
        m_serial_port->setPortName(port_num);

        if(m_serial_port->open(QIODevice::ReadWrite))
        {
            //设置波特率
            m_serial_port->setBaudRate(baud_rate);

            //设置数据位
            m_serial_port->setDataBits((QSerialPort::DataBits)data_bits);

            //设置停止位
            m_serial_port->setStopBits((QSerialPort::StopBits)stop_bits);

            //设置校验位
            m_serial_port->setParity((QSerialPort::Parity)parity);

            //设置流控制
            m_serial_port->setFlowControl(QSerialPort::NoFlowControl);
            m_first_status_label->setStyleSheet("color:black;");
            m_first_status_label->setText(port_num + "已打开");

            connect(m_serial_port,&QSerialPort::readyRead,this,&MainWindow::readSerial);
        }
        else
        {
            QMessageBox::about(NULL, "提示", "串口无法打开\r\n不存在或已被占用");
            m_first_status_label->setStyleSheet("color:red;");
            m_first_status_label->setText(port_num + "无法打开");
            return;
        }
        g_UART_open_flag=true;
    }
    else
    {
        m_serial_port->clear();
        m_serial_port->close();
        m_serial_port->deleteLater();

        g_UART_open_flag=false;

        m_first_status_label->setStyleSheet("color:black;");
        m_first_status_label->setText(port_num + "已关闭");
    }
}

void MainWindow::readSerial()
{
    m_rx_data=m_serial_port->readAll();
    if(!m_rx_data.isEmpty())
    {
        procUARTData();  //解包
        dealRcvPackData();  //数据分类
    }
}

void MainWindow::writeSerial(QByteArray data)
{
    if(m_serial_port!=nullptr)
    {
        if(m_serial_port->isOpen())
        {
            m_serial_port->write(data);
        }
    }
}

void MainWindow::recPRBType(QString type,QByteArray data)
{
    m_prb_type=type;
    writeSerial(data);
}

void MainWindow::menuSaveData()
{

}

void MainWindow::procUARTData()
{
    char* buf;
    if(m_rx_data.size()>0)
    {
        buf = m_rx_data.data();
    }
}

void MainWindow::dealRcvPackData()
{
    int headIndex = -1;
    int tailIndex = -1;

    m_mutex.lock();
    headIndex = m_pack_head;  //串口进来的数据的序号
    tailIndex = m_pack_tail;  //处理串口数据的序号
    m_mutex.unlock();

    if(headIndex < tailIndex)
    {
        headIndex = headIndex + PACK_QUEUE_CNT;
    }

    int index;
    int cnt = headIndex - tailIndex;

    for(int i = tailIndex; i < headIndex; i++)
    {
        index = i % PACK_QUEUE_CNT;
        //根据模块ID处理数据包
        switch(m_pack_after_unpack_array[index][0])
        {
        case DAT_TEMP:
            analyzeTempData(m_pack_after_unpack_array[index]);
            break;
        default:
            break;
        }
    }

    m_mutex.lock();
    m_pack_tail = (m_pack_tail + cnt) % PACK_QUEUE_CNT;
    m_mutex.unlock();
}

bool MainWindow::unpackRcvData(uchar recData)
{
    bool findPack = false;
    findPack = m_pack_unpack->unpackData(recData);

    if(findPack)
    {
        m_pack_after_unpack_list = m_pack_unpack->getUnpackRslt();  //获取解包结果

        if(m_pack_after_unpack_list.size() > 10)
        {
            QMessageBox::information(NULL, tr("Info"), tr("长度异常"), "确定");
        }

        int head = (m_pack_head + 1) % PACK_QUEUE_CNT;

        for(int i = 0; i < 8; i++)
        {
            m_pack_after_unpack_array[head][i] = m_pack_after_unpack_list[i];
        }

        m_mutex.lock();
        m_pack_head = (m_pack_head + 1) % PACK_QUEUE_CNT;

        if(m_pack_tail == -1)
        {
            m_pack_tail = 0;
        }

        m_mutex.unlock();
    }

    return findPack;
}

void MainWindow::analyzeTempData(uchar pack_after_unpack[])
{
    float temp1Data;          //通道1体温数据
    float temp2Data;          //通道2体温数据
    bool temp1Lead;           //通道1导联状态
    bool temp2Lead;           //通道2导联状态

    int data;
    switch(pack_after_unpack[1])
    {
    case DAT_TEMP_DATA:
        data = pack_after_unpack[2];
        temp1Lead = (data & 0x01) != 1;
        temp2Lead = ((data >> 1) & 0x01) != 1;
        data = pack_after_unpack[3];
        data = (data << 8) | pack_after_unpack[4];
        temp1Data = (float)(data / 10.0);
        data = pack_after_unpack[5];
        data = (data << 8) | pack_after_unpack[6];
        temp2Data = (float)(data / 10.0);

        if(temp1Lead)
        {
            ui->temp1LeadLabel->setText("T1导联");
            ui->temp1LeadLabel->setStyleSheet("color:green;");
            ui->temp1ValLabel->setText(QString::number(temp1Data));
        }
        else
        {
            ui->temp1LeadLabel->setText("T1脱落");
            ui->temp1LeadLabel->setStyleSheet("color:red;");
            ui->temp1ValLabel->setText("--");
        }

        if(temp2Lead)
        {
            ui->temp2LeadLabel->setText("T2导联");
            ui->temp2LeadLabel->setStyleSheet("color:green;");
            ui->temp2ValLabel->setText(QString::number(temp2Data));
        }
        else
        {
            ui->temp2LeadLabel->setText("T2脱落");
            ui->temp2LeadLabel->setStyleSheet("color:red;");
            ui->temp2ValLabel->setText("--");
        }

        break;

    default:
        break;
    }
}
